home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / button.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  288 lines

  1. /*
  2.  * button.c
  3.  *
  4.  * Forms Object class: BUTTON, LIGHTBUTTON, ROUNDBUTTON
  5.  *
  6.  * Written by: Mark Overmars
  7.  *
  8.  * Version 2.2 a
  9.  * Date: May 25, 1993
  10.  */
  11.  
  12. #include <malloc.h>
  13. #include "gl/gl.h"
  14. #include <sys/types.h>
  15. #include "forms.h"
  16.  
  17. /* Object specific information */
  18. typedef struct{
  19.    int val;        /* whether on */
  20.    int mousebut;    /* Number of the mouse button that caused the push */
  21.    int timdel;        /* time delay since last touch (for TOUCH buttons)*/
  22. } SPEC;
  23.  
  24. /********** DRAWING *************/
  25.  
  26. static void draw_button(FL_OBJECT *ob)
  27. /* Draws the object */
  28. {
  29.   int col;
  30.   if (((SPEC *)(ob->spec))->val) col = ob->col2; else col = ob->col1;
  31.   if (ob->belowmouse && col == FL_BUTTON_COL1) col = FL_BUTTON_MCOL1;
  32.   if (ob->belowmouse && col == FL_BUTTON_COL2) col = FL_BUTTON_MCOL2;
  33.   if (ob->boxtype == FL_UP_BOX && ((SPEC *)(ob->spec))->val)
  34.     fl_drw_box(FL_DOWN_BOX,ob->x,ob->y,ob->w,ob->h,col,FL_BUTTON_BW);
  35.   else
  36.     fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,col,FL_BUTTON_BW);
  37.   fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  38.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  39.   if (ob->type == FL_RETURN_BUTTON)
  40.     fl_drw_text(0,ob->x+ob->w-0.8*ob->h,ob->y+0.2*ob->h,
  41.             0.6*ob->h,0.6*ob->h,ob->lcol,0.0,0,"@returnarrow");
  42. }
  43.  
  44. static void draw_lightbutton(FL_OBJECT *ob)
  45. /* Draws the lightbutton */
  46. {
  47.   int c1,c2, libox;
  48.   float xx,yy,ww,hh;
  49.   /* Draw the box */
  50.   if (ob->belowmouse) c1 = FL_LIGHTBUTTON_MCOL; else c1 = FL_LIGHTBUTTON_TOPCOL;
  51.   if (((SPEC *)(ob->spec))->val) c2 = ob->col2; else c2 = ob->col1;
  52.   fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,c1,FL_LIGHTBUTTON_BW1);
  53.   /* Calculate and draw the light */
  54.   hh = ob->h - 3.0*FL_LIGHTBUTTON_BW1 - 1.0;
  55.   if (hh < FL_LIGHTBUTTON_MINSIZE) hh = FL_LIGHTBUTTON_MINSIZE;
  56.   ww = 0.5 * hh;
  57.   if (ww < FL_LIGHTBUTTON_MINSIZE) ww = FL_LIGHTBUTTON_MINSIZE;
  58.   if (ww > ob->w / 5.0) ww = ob->w / 5.0;
  59.   xx = ob->x + 1.5*FL_LIGHTBUTTON_BW1 + 1.0;
  60.   yy = ob->y + ob->h/2.0 - hh/2.0;
  61.   switch (ob->boxtype)
  62.   {
  63.     case FL_UP_BOX:             libox = FL_DOWN_BOX; break;
  64.     case FL_DOWN_BOX:           libox = FL_DOWN_BOX; break;
  65.     case FL_FRAME_BOX:          libox = FL_FRAME_BOX; break;
  66.     case FL_ROUNDED_BOX:        libox = FL_ROUNDED_BOX; break;
  67.     case FL_RFLAT_BOX:          libox = FL_ROUNDED_BOX; break;
  68.     case FL_RSHADOW_BOX:        libox = FL_ROUNDED_BOX; break;
  69.     default:                    libox = FL_BORDER_BOX; break;
  70.   }
  71.   fl_drw_box(libox,xx,yy,ww,hh,c2,FL_LIGHTBUTTON_BW2);
  72.   /* Draw the label */
  73.   if (ob->align == FL_ALIGN_CENTER)
  74.     fl_drw_text(FL_ALIGN_LEFT,xx+ww,ob->y,0.0,ob->h,
  75.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  76.   else
  77.     fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  78.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  79.   if (ob->type == FL_RETURN_BUTTON)
  80.     fl_drw_text(0,ob->x+ob->w-0.8*ob->h,ob->y+0.2*ob->h,
  81.             0.6*ob->h,0.6*ob->h,ob->lcol,0.0,0,"@returnarrow");
  82. }
  83.  
  84. static void draw_roundbutton(FL_OBJECT *ob)
  85. /* Draws a round button */
  86. {
  87.   int c1;
  88.   float xx,yy,rr;
  89.   if (ob->belowmouse) c1 = FL_ROUNDBUTTON_MCOL; else c1 = FL_ROUNDBUTTON_TOPCOL;
  90.   fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,c1,FL_ROUNDBUTTON_BW);
  91.   xx = ob->x + 0.4*ob->h;
  92.   yy = ob->y + 0.5*ob->h;
  93.   rr = 0.4*ob->h - 1.5*FL_ROUNDBUTTON_BW;
  94.   fl_color(ob->col1);
  95.   circf(xx,yy,rr);
  96.   fl_color(BLACK);
  97.   circ(xx,yy,rr);
  98.   if (((SPEC *)(ob->spec))->val)
  99.   {
  100.     fl_color(ob->col2);
  101.     circf(xx,yy,0.8*rr);
  102.     fl_color(BLACK);
  103.     circ(xx,yy,0.8*rr);
  104.   }
  105.   if (ob->align == FL_ALIGN_CENTER)
  106.     fl_drw_text(FL_ALIGN_LEFT,xx+rr,ob->y,0.0,ob->h,
  107.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  108.   else
  109.     fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  110.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  111.   if (ob->type == FL_RETURN_BUTTON)
  112.     fl_drw_text(0,ob->x+ob->w-0.8*ob->h,ob->y+0.2*ob->h,
  113.             0.6*ob->h,0.6*ob->h,ob->lcol,0.0,0,"@returnarrow");
  114. }
  115.  
  116. static int handle_it(FL_OBJECT *ob, int event, float mx, float my, char key)
  117. /* Handles an event */
  118. {
  119.   static int oldval;
  120.   int newval;
  121.   SPEC *sp = ((SPEC *)(ob->spec));
  122.   switch (event)
  123.   {
  124.     case FL_DRAW:
  125.     if (ob->type != FL_HIDDEN_BUTTON && ob->type != FL_HIDDEN_RET_BUTTON)
  126.       if (ob->objclass == FL_BUTTON)           draw_button(ob);
  127.        else if (ob->objclass == FL_LIGHTBUTTON) draw_lightbutton(ob);
  128.        else if (ob->objclass == FL_ROUNDBUTTON) draw_roundbutton(ob);
  129.     return 0;
  130.     case FL_ENTER:
  131.     case FL_LEAVE:
  132.         fl_redraw_object(ob);
  133.     return 0;
  134.     case FL_PUSH:
  135.         oldval = sp->val;
  136.         sp->val = ! sp->val;
  137.     sp->mousebut = (int) key;
  138.     sp->timdel = 1;
  139.         fl_redraw_object(ob);
  140.     return (ob->type == FL_INOUT_BUTTON || ob->type == FL_TOUCH_BUTTON);
  141.     case FL_RELEASE:
  142.     sp->mousebut = (int) key;
  143.     if (ob->type == FL_RADIO_BUTTON)
  144.         return 1;
  145.     else if (ob->type == FL_PUSH_BUTTON)
  146.         return (sp->val != oldval);
  147.     else if (sp->val == 0) 
  148.         return 0;
  149.     sp->val = 0;
  150.         fl_redraw_object(ob);
  151.     return (ob->type != FL_TOUCH_BUTTON);
  152.     case FL_MOUSE:
  153.     if (ob->type != FL_RADIO_BUTTON)
  154.     {
  155.         if (mx<ob->x || mx>ob->x+ob->w || my<ob->y || my>ob->y+ob->h)
  156.         newval = oldval;
  157.         else
  158.         newval = !oldval;
  159.         if (sp->val != newval)
  160.             { sp->val = newval; fl_redraw_object(ob);}
  161.     }
  162.     return (sp->val && ob->type == FL_TOUCH_BUTTON && sp->timdel++ % 12 == 0);
  163.     case FL_SHORTCUT:
  164.     if (ob->type == FL_PUSH_BUTTON)
  165.       { sp->val = ! sp->val; fl_redraw_object(ob);}
  166.     return (ob->type != FL_RADIO_BUTTON);
  167.     case FL_FREEMEM:
  168.     free(ob->spec);
  169.     return 0;
  170.   }
  171.   return 0;
  172. }
  173.  
  174. static FL_OBJECT *create_it(int objclass, int type,
  175.             float x, float y, float w, float h, const char *label)
  176. /* Creates an object */
  177. {
  178.   FL_OBJECT *ob;
  179.   ob = fl_make_object(objclass,type,x,y,w,h,label,handle_it);
  180.   if (type == FL_RADIO_BUTTON) ob->radio = 1;
  181.   if (type == FL_RETURN_BUTTON || type == FL_HIDDEN_RET_BUTTON)
  182.     fl_set_object_shortcut(ob,"^M");
  183.   ob->spec = (int *) fl_malloc(sizeof(SPEC));
  184.   ((SPEC *)(ob->spec))->val = 0;
  185.   ((SPEC *)(ob->spec))->timdel = 0;
  186.   return ob;
  187. }
  188.  
  189. /*------------------------------*/
  190.  
  191. void fl_set_button(FL_OBJECT *ob, int pushed)
  192. /* Sets the button */
  193. {
  194.   ((SPEC *)(ob->spec))->val = pushed;
  195.   if (ob->type == FL_RADIO_BUTTON) ob->pushed =pushed;
  196.   fl_redraw_object(ob);
  197. }
  198.  
  199. int fl_get_button(FL_OBJECT *ob)
  200. /* Returns value of the button */
  201.   { return ((SPEC *)(ob->spec))->val; }
  202.  
  203. int fl_get_button_numb(FL_OBJECT *ob)
  204. /* Returns the number of the last used mouse button */
  205.   { return ((SPEC *)(ob->spec))->mousebut; }
  206.  
  207. void fl_set_button_shortcut(FL_OBJECT *ob, const char *str)
  208. /* Sets the shortcut for the button */
  209.   if (ob->type == FL_RADIO_BUTTON)
  210.     fl_error("fl_set_button_shortcut", "Cannot set shortcuts for radio buttons.");
  211.   else
  212.     fl_set_object_shortcut(ob,str);
  213. }
  214.  
  215. /*------------------------------*/
  216.  
  217. FL_OBJECT *fl_create_button(int type,float x,float y,float w,float h,const
  218. char *label)
  219. /* creates an object */
  220. {
  221.   FL_OBJECT *ob;
  222.   ob = create_it(FL_BUTTON,type,x,y,w,h,label);
  223.   ob->boxtype = FL_BUTTON_BOXTYPE;
  224.   ob->col1 = FL_BUTTON_COL1;
  225.   ob->col2 = FL_BUTTON_COL2;
  226.   ob->align = FL_BUTTON_ALIGN;
  227.   ob->lcol = FL_BUTTON_LCOL;
  228.   return ob;
  229. }
  230.  
  231. FL_OBJECT *fl_create_lightbutton(int type,float x,float y,float w,float h,
  232. const char *label)
  233. /* creates an object */
  234. {
  235.   FL_OBJECT *ob;
  236.   ob = create_it(FL_LIGHTBUTTON,type,x,y,w,h,label);
  237.   ob->boxtype = FL_LIGHTBUTTON_BOXTYPE;
  238.   ob->col1 = FL_LIGHTBUTTON_COL1;
  239.   ob->col2 = FL_LIGHTBUTTON_COL2;
  240.   ob->align = FL_LIGHTBUTTON_ALIGN;
  241.   ob->lcol = FL_LIGHTBUTTON_LCOL;
  242.   return ob;
  243. }
  244.  
  245. FL_OBJECT *fl_create_roundbutton(int type,float x,float y,float w,float h,
  246. const char *label)
  247. /* creates an object */
  248. {
  249.   FL_OBJECT *ob;
  250.   ob = create_it(FL_ROUNDBUTTON,type,x,y,w,h,label);
  251.   ob->boxtype = FL_ROUNDBUTTON_BOXTYPE;
  252.   ob->col1 = FL_ROUNDBUTTON_COL1;
  253.   ob->col2 = FL_ROUNDBUTTON_COL2;
  254.   ob->align = FL_ROUNDBUTTON_ALIGN;
  255.   ob->lcol = FL_ROUNDBUTTON_LCOL;
  256.   return ob;
  257. }
  258.  
  259. FL_OBJECT *fl_add_button(int type,float x,float y,float w,float h,const char *label)
  260. /* Adds an object */
  261. {
  262.   FL_OBJECT *ob;
  263.   ob = fl_create_button(type,x,y,w,h,label);
  264.   fl_add_object(fl_current_form,ob);
  265.   return ob;
  266. }
  267.  
  268. FL_OBJECT *fl_add_lightbutton(int type,float x,float y,float w,float h,const
  269. char *label)
  270. /* Adds an object */
  271. {
  272.   FL_OBJECT *ob;
  273.   ob = fl_create_lightbutton(type,x,y,w,h,label);
  274.   fl_add_object(fl_current_form,ob);
  275.   return ob;
  276. }
  277.  
  278. FL_OBJECT *fl_add_roundbutton(int type,float x,float y,float w,float h,const
  279. char *label)
  280. /* Adds an object */
  281. {
  282.   FL_OBJECT *ob;
  283.   ob = fl_create_roundbutton(type,x,y,w,h,label);
  284.   fl_add_object(fl_current_form,ob);
  285.   return ob;
  286. }
  287.